package com.model.region
{
	import com.EffectTypes;
	import com.IconCanvas;
	import com.model.InteractivePage;
	
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.DisplayObject;
	import flash.events.MouseEvent;
	import flash.external.ExternalInterface;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	
	import mx.containers.Canvas;
	import mx.controls.Alert;
	import mx.controls.Button;
	import mx.controls.Image;
	import mx.controls.LinkButton;
	import mx.core.BitmapAsset;
	import mx.effects.Effect;
	import mx.effects.Fade;
	import mx.effects.Glow;
	import mx.effects.Iris;
	import mx.effects.WipeDown;
	import mx.effects.WipeLeft;
	import mx.effects.WipeRight;
	import mx.effects.WipeUp;
	
	public class Region
	{
		private var _regionX:Number = 0;
		private var _regionY:Number = 0;
		private var _regionWidth:Number = 0;
		private var _regionHeight:Number = 0;
		private var _type:String = "";
		private var _extraData:String = "";
		
		private var _regionId:Number = -1;
		private var _page:InteractivePage;
		
		private var _displayObject:DisplayObject = null;
		
		[Embed(source="assets/img/link.png")]
        private var iconClass:Class;
        
	   	[Embed(source="assets/icons/lightbulb_on.png")]
	   	public var iconLight:Class;
   		
   		[Embed(source="assets/icons/arrowRight.png")]
	   	public var iconRight:Class;
   		
   		[Embed(source="assets/icons/arrowUp.png")] 
	   	public var iconUp:Class;
	   	
	   	[Embed(source="assets/icons/arrowLeft.png")]
	   	public var iconLeft:Class;
	   	
	   	[Embed(source="assets/icons/arrowDown.png")]
	   	public var iconDown:Class;
	   	
        private var iconObject:BitmapAsset = new iconClass() as BitmapAsset;
        
        private static const EFFECT_DURATION:Number = 2000;
		
		public function Region(page:InteractivePage)
		{
			_page = page;
		}
		
		public function get displayObject():DisplayObject {
			if(_displayObject == null) {
				switch(_type) {
					case "link":
						_displayObject = new LinkButton();
						LinkButton(_displayObject).addEventListener(MouseEvent.CLICK, function():void {
							if (ExternalInterface.available) {
								ExternalInterface.call("openNewWindow", _extraData.split("%$")[1], _extraData.split("%$")[2], _extraData.split("%$")[3]);
							} else {
								Alert.show("ExternalInterface is not supported. This will prevent the popup windows");
							}
						});
						LinkButton(_displayObject).label = _extraData.split("%$")[0];
						break;
					case "icon":
						var bitmap:Bitmap = new Bitmap(iconObject.bitmapData);
						for each(var entry:Region in _page.regions) {
							if(entry.type == "rectangle" && entry.regionId == parseInt(_extraData)) {
								_displayObject = new IconCanvas(entry);
								IconCanvas(_displayObject).rawChildren.addChild(bitmap);
								_displayObject.addEventListener(MouseEvent.CLICK, previewEffect);
							}
						}
						break;
					case "iconLink":
						_displayObject = new Button();
						Button(_displayObject).setStyle("icon",getButtonClass(_extraData.split("%$")[4]));
						Button(_displayObject).width = 7;
						Button(_displayObject).height = 13;
						Button(_displayObject).addEventListener(MouseEvent.CLICK, function():void {
							if (ExternalInterface.available) {
								ExternalInterface.call("openNewWindow", _extraData.split("%$")[1], _extraData.split("%$")[2], _extraData.split("%$")[3]);
							} else {
								Alert.show("ExternalInterface is not supported. This will prevent the popup windows");
							}
						});
						break;
					case "rectangle":
						_displayObject = createWhiteRectangularCanvas(new Rectangle(_regionX, _regionY, _regionWidth, regionHeight));
						break;
				}
				if(_displayObject) {
					_displayObject.x = _regionX;
					_displayObject.y = _regionY;					
				}
			}
			return _displayObject;
		}
		
		private function getButtonClass(type:String):Class {
			var iconType:Class; 
			switch(type) {
				case "iconLight":
					iconType=iconLight;
					break;
				case "iconRight":
					iconType=iconRight;
					break;
				case "iconLeft":
					iconType=iconLeft;
					break;
				case "iconUp":
					iconType=iconUp;
					break;
				case "iconDown":
					iconType=iconDown;
					break;
			}
			return iconType;
		}
		
		private function previewEffect(e:MouseEvent):void {
			var region:Region = IconCanvas(e.target).relatedRegion;
			var relatedRectangle:Rectangle = new Rectangle(region.regionX, region.regionY, region.regionWidth, region.regionHeight);
			var canvas:Canvas=copyRectangle(_page.image, relatedRectangle);
			
			_page.addChild(canvas);
 			
 			// apply the effect to the new canvas
 			var effect:Effect= createEffectOfType(parseInt(region.extraData)); 			
 			effect.target=canvas;
 			effect.stop();
 			effect.play();
		}
		
		
		//copies a rectangle from the source image to a new canvas, and returns this new canvas
		private function copyRectangle(sourceImage:Image,sourceRectangle:Rectangle):Canvas {
			var bitmapData:BitmapData = new BitmapData(sourceRectangle.width,sourceRectangle.height);
 			var point:Point= new Point(0,0);
 			bitmapData.copyPixels(Bitmap(sourceImage.content).bitmapData,sourceRectangle,point);
 			var bitmap:Bitmap= new Bitmap(bitmapData);
 			bitmap.x=0;
 			bitmap.y=0;
 			var canvas:Canvas = new Canvas();
 			canvas.x = sourceRectangle.x;
 			canvas.y = sourceRectangle.y;
 			canvas.rawChildren.addChild(bitmap);
 			return canvas;
		}
		
		private function createWhiteRectangularCanvas(rectangle:Rectangle):Canvas {
			var whiteRectangleBitmapData:BitmapData = new BitmapData(rectangle.width,rectangle.height,false,0xffffff);
 			var whiteRectangleBitmap:Bitmap = new Bitmap(whiteRectangleBitmapData);
 			whiteRectangleBitmap.x = 0;
 			whiteRectangleBitmap.y = 0;
 			
 			var whiteRectangleCanvas:Canvas = new Canvas();
 			whiteRectangleCanvas.x = rectangle.x;
 			whiteRectangleCanvas.y = rectangle.y;
 			whiteRectangleCanvas.rawChildren.addChild(whiteRectangleBitmap);
				
			return whiteRectangleCanvas;				
		}
			
		//return an effect of the given type
		private function createEffectOfType(effectType:Number):Effect {
			var effect:Effect;
 			switch (effectType) {
 				case EffectTypes.FADE:
 					effect = new Fade();
 					break;	
 				case EffectTypes.WIPE_RIGHT:
 					effect = new WipeRight();
 					break;
 				case EffectTypes.WIPE_LEFT:
 					effect = new WipeLeft();
 					break;
 				case EffectTypes.WIPE_UP:
 					effect = new WipeUp();
 					break;
 				case EffectTypes.WIPE_DOWN:
 					effect = new WipeDown();
 					break;
 				case EffectTypes.IRIS:
 					effect = new Iris();
 					break;
 				case EffectTypes.GLOW:
 					effect = new Glow();
 					break;
 			}
 			effect.duration = EFFECT_DURATION;
 			return effect;
		}
		
		//////////////////////////////// Getter & Setters /////////////////////////////////////
		
		public function get regionId():Number {
			return _regionId;
		}
		public function set regionId(val:Number):void {
			_regionId = val;
		}
		
		public function get regionX():Number {
			return _regionX;
		}
		public function set regionX(val:Number):void {
			_regionX = val;
		}
		
		public function get regionY():Number {
			return _regionY;
		}
		public function set regionY(val:Number):void {
			_regionY = val;
		}
		
		public function get regionWidth():Number {
			return _regionWidth;
		}
		public function set regionWidth(val:Number):void {
			_regionWidth = val;
		}
		public function get regionHeight():Number {
			return _regionHeight;
		}
		public function set regionHeight(val:Number):void {
			_regionHeight = val;
		}
		public function get type():String {
			return _type;
		}
		public function set type(val:String):void {
			_type = val;
		}
		
		public function get extraData():String {
			return _extraData;
		}
		public function set extraData(val:String):void {
			_extraData = val;
		}

	}
}